package com.rxyb.security.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rxyb.security.db.bean.SysRole;
import com.rxyb.security.db.bean.SysUser;
import com.rxyb.security.db.bean.SysUserRole;
import com.rxyb.security.db.bean.SysUsercustom;
import com.rxyb.security.db.dao.SysRoleMapper;
import com.rxyb.security.db.dao.SysUserMapper;
import com.rxyb.security.db.dao.SysUserRoleMapper;
import com.rxyb.security.handler.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.access.vote.UnanimousBased;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

/**
 * @author YJH
 * @version 1.0
 * @description Web 认证的怕配置
 * @date 2020/5/15  15:51
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        /* 开启跨域共享，  跨域伪造请求限制=无效 */
        http.cors().and().csrf().disable();

        /* 开启授权认证 */
        http.authorizeRequests().anyRequest().authenticated();

        /* 登录配置 */
        http.formLogin().loginProcessingUrl("/login");

        /* 登录失败后的处理 */
        http.formLogin().failureHandler(new LoginFailHandler());

        /* 登录过期/未登录 处理 */
        http.exceptionHandling().authenticationEntryPoint(new LoginExptionHandler());

        /* 登录成功后的处理 */
        http.formLogin().successHandler(new LoginSuccessHandler());

        /* rest 无状态 无session */
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        /* 配置token验证过滤器 */
        http.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected UserDetailsService userDetailsService() {
        return username -> {
            if (null == username || username.trim().length() <= 0) {
                throw new UsernameNotFoundException("用户名为空");
            }
//            // 查询用户信息
            QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
            sysUserQueryWrapper.lambda().eq(SysUser::getUsername, username);
            SysUser sysUser1 = sysUserMapper.selectOne(sysUserQueryWrapper);
            // 查询权限信息
            QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
            sysUserRoleQueryWrapper.lambda().eq(SysUserRole::getSysUserId, sysUser1.getId());
            List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(sysUserRoleQueryWrapper);
            //  查询权限
            QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
            sysRoleQueryWrapper.lambda().in(SysRole::getId, str(sysUserRoles));
            List<SysRole> sysRoles = sysRoleMapper.selectList(sysRoleQueryWrapper);
            SysUsercustom sysUser = new SysUsercustom();
            sysUser.setId(sysUser1.getId());
            sysUser.setUsername(sysUser1.getUsername());
            sysUser.setPassword(sysUser1.getPassword());
            sysUser.setSysRoleList(sysRoles);
            if (null != sysUser) {

                return sysUser;
            }
            throw new UsernameNotFoundException("用户信息不存在");
        };
    }

    private List<Long> str(List<SysUserRole> roles) {
        List<Long> list = new ArrayList<>();
        roles.forEach(e -> {
            list.add(e.getSysRoleId());
        });
        return list;
    }


    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }
        };
    }


}
